<?php
/*
    morph.class
*/
require_once("config.inc.php");
class morph {
    public static $NBVAR = 8;
    private $OptimunOrder = 7;
    private $nDirection = 0;
    private $nOrder = 0;

    private $MaxY = 0;
    private $xy;

    public $dx = array();
    public $dy = array();
    private $gene = array();
    public $mgenome;
    private $computed;
    private $transcriptioni = 1;
    
    private $FromPt = array(),$ToPt = array();
    public $json;
    
    public function new_morph (genome $gen,$trans) {
	$this->mgenome = $gen;
	$this->gene = $this->mgenome->chromosome;
	//var_dump($this->gene);
	$this->MaxY = 0;
	$this->transcription = $trans;
	$this->computed = false;	
    }
    public function phenotype () {
	if ( $this->computed == false) {
	    $this->transcript();
	}
	//var_dump($this->MaxY);
	//print_r($this->FromPt[0]);
	//print_r($this->ToPt[0]);

	$NFromPt = array(); 
	$NToPt = array();;
	foreach ($this->FromPt as $key => $value) {
	    //echo $key ." ". $value."\n";
	    //echo $value[0]." ".($value[1] - $this->MaxY)."\n";
	    $NFromPt[] = array($value[0],$value[1] - $this->MaxY);
	}
	foreach ($this->ToPt as $key => $value) {
	    //echo $key ." ". $value."\n";
	    //echo $value[0]." ".($value[1] - $this->MaxY)."\n";
	    $NToPt[] = array($value[0],$value[1] - $this->MaxY);
	}
	//var_dump($this->NFromPt);
	return $this->json = json_encode(array($this->FromPt,$this->ToPt));

    }

/* pushGene */
    public function push_gene ($x1,$y1,$x2,$y2) {
	$x1 = $x1;
	$y1 = $y1;
	$x2 = $x2;
	$y2 = $y2;
	if ( $y1 > $this->MaxY ) {
	    $this->MaxY = $y1;
	} else if ( $y2 > $this->MaxY ) {
	    $this->MaxY = $y2;
	}
	//echo $x1." ".$y1." ".$x2." ".$y2."\n";
	$this->FromPt[] = array($x1,$y1);
	$this->ToPt[] = array($x2,$y2);	
    }
/* Isvalid  */
    public function is_valid () {
	return $this->mgenome->is_valid();
    }
/* mutate  */
    public function mutate ($severity,random $r) {
	$this->mgenome->mutate($severity,$r);
	$this->computed = false;
    }
/* reTranscript */
    public function retranscript ($trans) {
	$this->computed = false;
	$this->transcription = $trans;
	$this->transcript();
    }
/* transcript */
    private function transcript () {
	    $this->dx[0] = - $this->gene[1] / 4;
	    $this->dx[1] = - $this->gene[0] / 4;
	    $this->dx[2] = $this->gene[3] / 2;
	    $this->dx[3] =  $this->gene[0] / 2;
	    $this->dx[4] = $this->gene[1] / 2;
	    $this->dx[5] = $this->gene[2] / 2;
	    $this->dx[6] = - $this->dx[2] / 2;
	    $this->dx[7] = - $this->dx[5] / 2;

	    $this->dy[0] = ($this->gene[5]) / 2;
	    $this->dy[1] = ($this->gene[4]);
	    $this->dy[2] =($this->gene[3]);
	    $this->dy[3] = - ($this->gene[4]);
	    $this->dy[4] = - ($this->gene[5]);
	    $this->dy[5] = ($this->gene[6]);
	    $this->dy[6] = ($this->gene[0]);
	    $this->dy[7] = - ($this->dy[5]);

	    if ($this->transcription == 1) {
		$this->gene[8] = $this->OptimunOrder;
	    }
	    else{
		$this->gene[8] = ($this->gene[8] < 0) ? - $this->gene[8] : $this->gene[8];
		$this->gene[8] = ($this->gene[8] < 3) ? 3 : $this->gene[8];
	    }

	    $this->nOrder = $this->gene[8];

	    $this->tree (0, 0, $this->nOrder, $this->nDirection);
    }
/* tree */
    public function tree ($x,$y,$order,$dir) {
	if ( $dir < 0 ) {
	    $dir = 8 + $dir;
	}
	else if ( $dir >= 8 ) {
	    $dir = 8 - $dir;
	}
	$Xnew = $x + $order * ($this->dx[$dir]);
	$Ynew = $y + $order * ($this->dy[$dir]);



/*
	if ( $this->Xnew > 50 ) {
	    $this->Xnew = 50;
	}
	if ( $this->Xnew < -50 ) {
	    $this->Xnew = -50;
	}
*/
	$this->push_gene($x,$y,$Xnew,$Ynew);
	if ( $order > 0 ) {
	    $this->tree($Xnew,$Ynew,$order - 1,$dir - 1);
	    $this->tree($Xnew,$Ynew,$order - 1,$dir + 1);
	}
	$this->computed = true;
    }

}

// test
/*
$r = new random();
$t = new genome();
$tt = new morph();
$t->new_ran_genome($r);
$tt->new_morph($t,1);
$tt->phenotype();
*/
?>
